/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package queue;

import exceptions.EmptyQueueException;

/**
 *
 * @author pc
 */
public class ArrayQueue<E> implements Queue<E> {

    public static final int CAPACITY = 1024;
    private int N , f=0, r=0;
    private E[] Q;

    public ArrayQueue() {
        Q = (E[]) new Object[CAPACITY];
        N=CAPACITY;
    }

    public ArrayQueue(int capacity) {
        this.N = capacity;
        Q = (E[]) new Object[this.N];
      
    }

    @Override
    public int size() {
        return (N - f + r) % N;
    }

    @Override
    public boolean isEmpty() {
        return f == r;
    }

    @Override
    public E front() throws EmptyQueueException {
        if(isEmpty()) throw new EmptyQueueException("Impossibile prelevare front, Queue vuota");
        return Q[f];
    }
    
    public E rest() throws EmptyQueueException{
        if(isEmpty()) throw new EmptyQueueException("Impossibile prelevare rest, Queue vuota");
        return Q[r-1];
    }

    @Override
    public void enqueue(E element) {
        if (size() == N - 1) {
            E[] newArray = (E[]) new Object[N*2];
            for (int i = 0; i < size(); i++) 
                newArray[i] = Q[i];     
            
            N *= 2;
            Q=newArray;
            f=0;
            r=size();
            }
        
            Q[r] = element;
            r = (r + 1) % N;

        }
    
        @Override
        public E dequeue() throws EmptyQueueException {
            if (isEmpty()) throw new EmptyQueueException("La queue è gia vuota! impossibile fare");
            E tmp = Q[f];
            f = (f + 1) % N;
            return tmp;
        }

    }
